package org.devio.takephoto.uitl;

import ohos.agp.utils.Matrix;
import ohos.app.Context;
import ohos.media.image.ImagePacker;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;
import ohos.utils.net.Uri;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Author: crazycodeboy
 * Date: 2016/9/21 0007 20:10
 * Version:3.0.0
 * http://www.devio.org
 * GitHub:https://github.com/crazycodeboy
 * Email:crazycodeboy@gmail.com
 */
public class ImageRotateUtil {
    private static final String TAG = ImageRotateUtil.class.getSimpleName();

    public static ImageRotateUtil of() {
        return new ImageRotateUtil();
    }

    private ImageRotateUtil() {
    }

    /**
     * This method id used rotate image based on angel
     *
     * @param context context of our ability/fraction
     * @param path    URI path of our image
     */
    public void correctImage(Context context, Uri path) {
        if (null != path) {
            String imagePath = TUriParse.parseOwnUri(context, path);
            if (!TextUtils.isEmpty(imagePath)) {
                int degree;
                if ((degree = getBitmapDegree(imagePath)) != 0) {
                    ImageSource imageSource = ImageSource.create(imagePath, new ImageSource.SourceOptions());
                    PixelMap bitmap = imageSource.createPixelmap(new ImageSource.DecodingOptions());
                    if (bitmap == null) {
                        return;
                    }
                    PixelMap resultBitmap = rotateBitmapByDegree(bitmap, degree);
                    if (resultBitmap == null) {
                        return;
                    }
                    ImagePacker imagePacker = ImagePacker.create();
                    ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
                    packingOptions.format = TConstant.PC_IMAGE_JPEG;
                    File file = new File(imagePath);
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    imagePacker.initializePacking(bos.toByteArray(), 100, packingOptions);
                    FileOutputStream fos = null;
                    try {
                        fos = new FileOutputStream(file);
                        fos.write(bos.toByteArray());
                        bos.flush();
                        fos.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (fos != null) {
                                fos.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        try {
                            if (bos != null) {
                                bos.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    private int getBitmapDegree(String path) {
        int degree = 0;
        ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
        ImageSource exifInterface = ImageSource.create(path, sourceOptions);
        int orientation = exifInterface.getImagePropertyInt(TConstant.PC_ORIENTATION, Integer.parseInt("" + new ImageSource.DecodingOptions().rotateDegrees));
        switch (orientation) {
            case 90:
                degree = 90;
                break;
            case 180:
                degree = 180;
                break;
            case 270:
                degree = 270;
                break;
        }
        return degree;
    }

    /**
     * This method is used to rotate pixelmap based on angel
     *
     * @param bm     bitmap prepared after taking image from camera
     * @param degree degree to rotate your image
     * @return rotated PixelMap based on degree
     */
    private PixelMap rotateBitmapByDegree(PixelMap bm, int degree) {
        PixelMap returnBm = null;
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            returnBm = PixelMap.create(bm, new Rect(0, 0, bm.getImageInfo().size.width, bm.getImageInfo().size.height), new PixelMap.InitializationOptions());
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.release();
        }
        return returnBm;
    }
}
